home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / delivery / deliver.tz / deliver / addr.c next >
Encoding:
C/C++ Source or Header  |  1992-12-07  |  4.0 KB  |  221 lines

  1. /* $Header: addr.c,v 2.2 90/03/06 12:21:18 chip Exp $
  2.  *
  3.  * Operations on addresses, (ASCII representations of destinations).
  4.  *
  5.  * $Log:    addr.c,v $
  6.  * Revision 2.2  90/03/06  12:21:18  chip
  7.  * Move logging into log.c and address parsing into addr.c.
  8.  * New: error delivery file for messages that fail.
  9.  * Major rearrangement of delivery file code.
  10.  * 
  11.  */
  12.  
  13. #include "deliver.h"
  14.  
  15. /*----------------------------------------------------------------------
  16.  * Check an address for cleanliness.
  17.  * That is, make sure that it is devoid of shell metacharacters.
  18.  * And make sure it's got at least one character, too.
  19.  */
  20.  
  21. addr_clean(addr)
  22. char    *addr;
  23. {
  24.     char    *p;
  25.     static char sanitize[] = SANITIZE;
  26.  
  27.     if (*addr == 0)
  28.         return FALSE;
  29.  
  30.     for (p = addr; *p; ++p)
  31.     {
  32.         if (strchr(sanitize, *p))
  33.             return FALSE;
  34.     }
  35.  
  36.     return TRUE;
  37. }
  38.  
  39. /*----------------------------------------------------------------------
  40.  * Report the class of a string representation of a destination.
  41.  */
  42.  
  43. DCLASS
  44. addr_class(s)
  45. char    *s;
  46. {
  47.     char    *p;
  48.  
  49.     for (p = s; *p; ++p)
  50.     {
  51.         switch (*p)
  52.         {
  53.         case '!':
  54.             return CL_UUCP;
  55.         case ':':
  56.             return CL_MBOX;
  57.         case '|':
  58.             return CL_PROG;
  59.         case '?':
  60.             return CL_USER;
  61.         }
  62.     }
  63.  
  64.     return CL_USER;
  65. }
  66.  
  67. /*----------------------------------------------------------------------
  68.  * Parse a string representation of a destination.
  69.  * If dfile_ct is non-NULL, then a missing user name refers to that user;
  70.  *    otherwise, a missing user name refers to the effective user id.
  71.  * If dfile_ct is NULL, then we only permit user names and UUCP addresses;
  72.  *      otherwise, we permit all kinds of addresses.
  73.  */
  74.  
  75. DEST *
  76. addr_dest(s, dfile_ct)
  77. char    *s;
  78. CONTEXT    *dfile_ct;
  79. {
  80.     DEST    *d;
  81.     CONTEXT    *ct;
  82.     char    *buf, *p, *q, *user, *param;
  83.     char    sep;
  84.     int    i, legal;
  85.  
  86.     /*
  87.      * If this is NOT a delivery file, restrict address class
  88.      * to user and UUCP.
  89.      */
  90.  
  91.     if (!dfile_ct)
  92.     {
  93.         DCLASS    class;
  94.  
  95.         class = addr_class(s);
  96.         if ((class != CL_USER && class != CL_UUCP)
  97.          || strcmp(s, DFILE_DROP) == 0)
  98.         {
  99.             d = dest(s, CL_USER, (char *)NULL);
  100.             dest_err(d, E_DFONLY);
  101.             return d;
  102.         }
  103.     }
  104.  
  105.     /*
  106.      * Find the additional information after the user name.
  107.      * Bang means UUCP, colon means mailbox, pipe means pipe,
  108.      * question means error.
  109.      */
  110.  
  111.     for (i = 0; (sep = s[i]) != 0; ++i)
  112.     {
  113.         if (sep == '!' || sep == ':' || sep == '|' || sep == '?')
  114.             break;
  115.     }
  116.  
  117.     /*
  118.      * Deal with UUCP paths before the user-name parsing begins.
  119.      */
  120.  
  121.     if (sep == '!')
  122.         return dest(s, CL_UUCP, (char *)NULL);
  123.  
  124.     /*
  125.      * Copy string to local buffer so we can mangle it.
  126.      * Chop it up into user name and parameter.
  127.      */
  128.  
  129.     buf = copystr(s);
  130.     if (buf[i])
  131.         buf[i++] = 0;
  132.     user = buf;
  133.     param = buf + i;
  134.  
  135.     /*
  136.      * If user name is blank, provide default.
  137.      */
  138.  
  139.     if (*user == 0)
  140.         user = (dfile_ct ? dfile_ct : eff_ct)->ct_name;
  141.  
  142.     /*
  143.      * Determine if we can get there from here.
  144.      */
  145.  
  146.     if ((ct = name_context(user)) == NULL)
  147.         legal = TRUE;    /* we can report "no such user" later */
  148.     else if (dfile_ct)
  149.         legal = ok_context(dfile_ct->ct_uid, dfile_ct->ct_uid,
  150.                    dfile_ct->ct_gid, ct);
  151.     else
  152.         legal = ok_context(eff_uid, real_uid, real_gid, ct);
  153.  
  154.     /*
  155.      * Now take action based on address class.
  156.      */
  157.  
  158.     /* Could be "user|program" ... */
  159.  
  160.     if (sep == '|')
  161.         d = legal ? dest(user, CL_PROG, param) : NULL;
  162.  
  163.     /* Could be "user?error" ... */
  164.  
  165.     else if (sep == '?')
  166.     {
  167.         if (legal)
  168.         {
  169.             d = dest(user, CL_USER, (char *)NULL);
  170.             dest_err(d, E_ERRMSG);
  171.             d->d_errmsg = copystr(param);
  172.         }
  173.         else
  174.             d = NULL;
  175.     }
  176.  
  177.     /* Must be "user" or "user:mailbox" */
  178.  
  179.     else
  180.     {
  181.         /*
  182.          * Strip whitespace, eliminate duplicate slashes from
  183.          * mailbox filename.
  184.          */
  185.  
  186.         p = q = param;
  187.         while (*p)
  188.         {
  189.             if (isspace(*p))
  190.                 ++p;
  191.             else if ((*q++ = *p++) == '/')
  192.             {
  193.                 while (*p == '/')
  194.                     ++p;
  195.             }
  196.         }
  197.         *q = 0;
  198.  
  199.         /*
  200.          * Now that blanks are gone, we decide mailbox or not.
  201.          * Delaying this test means that "user" equals "user: ".
  202.          */
  203.  
  204.         if (*param)
  205.             d = legal ? dest(user, CL_MBOX, param) : NULL;
  206.         else
  207.             d = dest(user, CL_USER, (char *)NULL);
  208.     }
  209.  
  210.     /*
  211.      * We allocated the buffer; now we free it.
  212.      */
  213.  
  214.     free(buf);
  215.  
  216.     /* Return parsed destination. */
  217.  
  218.     return d;
  219. }
  220.  
  221.